package com.employment.service.impl;

import com.employment.dao.ChatConversationMapper;
import com.employment.dao.ChatMessageMapper;
import com.employment.dao.ChatParticipantMapper;
import com.employment.entity.ChatConversation;
import com.employment.entity.ChatMessage;
import com.employment.entity.ChatParticipant;
import com.employment.service.ChatService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 聊天服务实现类
 * 
 * @author Employment System
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements ChatService {
    
    private final ChatConversationMapper chatConversationMapper;
    private final ChatMessageMapper chatMessageMapper;
    private final ChatParticipantMapper chatParticipantMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatConversation createPrivateConversation(Long userId1, Long userId2) {
        log.info("创建私聊会话，用户1：{}，用户2：{}", userId1, userId2);
        
        // 检查是否已存在会话
        ChatConversation existingConversation = chatConversationMapper.selectPrivateConversation(userId1, userId2);
        if (existingConversation != null) {
            return existingConversation;
        }
        
        // 创建新会话
        ChatConversation conversation = new ChatConversation();
        conversation.setType(1); // 私聊
        conversation.setTitle("私聊");
        conversation.setCreatorId(userId1);
        conversation.setLastMessageTime(LocalDateTime.now());
        conversation.setStatus(1);
        conversation.setCreatedAt(LocalDateTime.now());
        conversation.setUpdatedAt(LocalDateTime.now());
        
        chatConversationMapper.insert(conversation);
        
        // 添加参与者
        addParticipant(conversation.getConversationId(), userId1, 1); // 发起者为管理员
        addParticipant(conversation.getConversationId(), userId2, 3); // 被邀请者为普通成员
        
        log.info("私聊会话创建成功，会话ID：{}", conversation.getConversationId());
        return conversation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatConversation createGroupConversation(Long creatorId, String title, String avatar, Long[] participantIds) {
        log.info("创建群聊会话，创建者：{}，标题：{}", creatorId, title);
        
        // 创建会话
        ChatConversation conversation = new ChatConversation();
        conversation.setType(2); // 群聊
        conversation.setTitle(title);
        conversation.setAvatar(avatar);
        conversation.setCreatorId(creatorId);
        conversation.setLastMessageTime(LocalDateTime.now());
        conversation.setStatus(1);
        conversation.setCreatedAt(LocalDateTime.now());
        conversation.setUpdatedAt(LocalDateTime.now());
        
        chatConversationMapper.insert(conversation);
        
        // 添加创建者为群主
        addParticipant(conversation.getConversationId(), creatorId, 3); // 群主
        
        // 添加其他参与者
        if (participantIds != null) {
            for (Long participantId : participantIds) {
                if (!participantId.equals(creatorId)) {
                    addParticipant(conversation.getConversationId(), participantId, 1); // 普通成员
                }
            }
        }
        
        log.info("群聊会话创建成功，会话ID：{}", conversation.getConversationId());
        return conversation;
    }

    @Override
    public List<ChatConversation> getUserConversations(Long userId) {
        log.info("获取用户会话列表，用户ID：{}", userId);
        return chatConversationMapper.selectByUserId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ChatMessage sendMessage(Long conversationId, Long senderId, Integer messageType, String content, 
                                  String fileUrl, String fileName, Long fileSize, String locationInfo) {
        log.info("发送消息，会话ID：{}，发送者：{}", conversationId, senderId);
        
        // 创建消息
        ChatMessage message = new ChatMessage();
        message.setConversationId(conversationId);
        message.setSenderId(senderId);
        message.setMessageType(messageType);
        message.setContent(content);
        message.setFileUrl(fileUrl);
        message.setFileName(fileName);
        message.setFileSize(fileSize);
        // 位置信息需要分别设置纬度、经度和地址
        if (locationInfo != null && locationInfo.contains(",")) {
            String[] parts = locationInfo.split(",");
            if (parts.length >= 2) {
                try {
                    message.setLocationLatitude(new java.math.BigDecimal(parts[0]));
                    message.setLocationLongitude(new java.math.BigDecimal(parts[1]));
                } catch (NumberFormatException e) {
                    log.warn("位置信息格式不正确: {}", locationInfo);
                }
            }
        }
        message.setIsRecall(0);
        message.setIsRead(0);
        message.setCreatedAt(LocalDateTime.now());
        message.setUpdatedAt(LocalDateTime.now());
        
        chatMessageMapper.insert(message);
        
        // 更新会话的最后消息信息
        chatConversationMapper.updateLastMessage(conversationId, message.getMessageId(), 
            message.getCreatedAt().toString());
        
        // 增加会话消息数量
        chatConversationMapper.increaseMessageCount(conversationId);
        
        log.info("消息发送成功，消息ID：{}", message.getMessageId());
        return message;
    }

    @Override
    public List<ChatMessage> getConversationMessages(Long conversationId, Integer page, Integer size) {
        log.info("获取会话消息列表，会话ID：{}，页码：{}，大小：{}", conversationId, page, size);
        
        Page<ChatMessage> pageObj = new Page<>(page, size);
        return chatMessageMapper.selectConversationMessagePage(pageObj, conversationId).getRecords();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean markAsRead(Long messageId, Long userId) {
        log.info("标记消息为已读，消息ID：{}，用户ID：{}", messageId, userId);
        
        ChatMessage message = chatMessageMapper.selectOneById(messageId);
        if (message == null) {
            return false;
        }
        
        // 更新参与者表中的最后阅读时间
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(
            message.getConversationId(), userId);
        if (participant != null) {
            participant.setLastReadMessageId(messageId);
            participant.setLastReadTime(LocalDateTime.now());
            participant.setUpdatedAt(LocalDateTime.now());
            chatParticipantMapper.update(participant);
        }
        
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean recallMessage(Long messageId, Long userId) {
        log.info("撤回消息，消息ID：{}，用户ID：{}", messageId, userId);
        
        ChatMessage message = chatMessageMapper.selectOneById(messageId);
        if (message == null) {
            return false;
        }
        
        // 只有发送者可以撤回消息
        if (!message.getSenderId().equals(userId)) {
            return false;
        }
        
        message.setIsRecall(1);
        message.setRecallTime(LocalDateTime.now());
        message.setUpdatedAt(LocalDateTime.now());
        
        int result = chatMessageMapper.update(message);
        return result > 0;
    }

    @Override
    public Integer getUnreadMessageCount(Long conversationId, Long userId) {
        log.info("获取未读消息数量，会话ID：{}，用户ID：{}", conversationId, userId);
        
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant == null || participant.getLastReadMessageId() == null) {
            return Math.toIntExact(chatMessageMapper.selectCountByQuery(new QueryWrapper()
                .eq("conversation_id", conversationId)));
        }
        
        return chatMessageMapper.countUnreadMessages(conversationId, userId, participant.getLastReadMessageId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean joinConversation(Long conversationId, Long userId, Long inviterId) {
        log.info("加入会话，会话ID：{}，用户ID：{}，邀请人：{}", conversationId, userId, inviterId);
        
        return addParticipant(conversationId, userId, 1); // 普通成员
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean leaveConversation(Long conversationId, Long userId) {
        log.info("退出会话，会话ID：{}，用户ID：{}", conversationId, userId);
        
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant == null) {
            return false;
        }
        
        participant.setStatus(0); // 已退出
        participant.setUpdatedAt(LocalDateTime.now());
        int result = chatParticipantMapper.update(participant);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setMuteStatus(Long conversationId, Long userId, boolean isMuted) {
        log.info("设置免打扰状态，会话ID：{}，用户ID：{}，状态：{}", conversationId, userId, isMuted);
        
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant == null) {
            return false;
        }
        
        participant.setIsMuted(isMuted ? 1 : 0);
        participant.setUpdatedAt(LocalDateTime.now());
        
        int result = chatParticipantMapper.update(participant);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setTopStatus(Long conversationId, Long userId, boolean isTop) {
        log.info("设置置顶状态，会话ID：{}，用户ID：{}，状态：{}", conversationId, userId, isTop);
        
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant == null) {
            return false;
        }
        
        participant.setIsTop(isTop ? 1 : 0);
        participant.setUpdatedAt(LocalDateTime.now());
        
        int result = chatParticipantMapper.update(participant);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteConversation(Long conversationId, Long userId) {
        log.info("删除会话，会话ID：{}，用户ID：{}", conversationId, userId);
        
        // 检查用户是否是会话参与者
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant == null) {
            return false;
        }
        
        // 逻辑删除会话
        ChatConversation conversation = new ChatConversation();
        conversation.setConversationId(conversationId);
        conversation.setStatus(0); // 禁用状态
        conversation.setUpdatedAt(LocalDateTime.now());
        
        int result = chatConversationMapper.update(conversation);
        return result > 0;
    }

    @Override
    public List<ChatParticipant> getConversationParticipants(Long conversationId) {
        log.info("获取会话参与者列表，会话ID：{}", conversationId);
        
        return chatParticipantMapper.selectByConversationId(conversationId);
    }

    @Override
    public List<ChatMessage> searchMessages(Long conversationId, String keyword, Long userId) {
        log.info("搜索消息，会话ID：{}，关键词：{}，用户ID：{}", conversationId, keyword, userId);
        
        // 检查用户是否是会话参与者
        if (!isConversationParticipant(conversationId, userId)) {
            return List.of();
        }
        
        return chatMessageMapper.searchMessages(conversationId, keyword, 100);
    }

    @Override
    public boolean isConversationParticipant(Long conversationId, Long userId) {
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        return participant != null && participant.getStatus() == 1;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void pinConversation(Long conversationId, Long userId, Boolean isPinned) {
        log.info("设置会话置顶，会话ID：{}，用户ID：{}，状态：{}", conversationId, userId, isPinned);
        
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant != null) {
            participant.setIsTop(isPinned ? 1 : 0);
            participant.setUpdatedAt(LocalDateTime.now());
            chatParticipantMapper.update(participant);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void muteConversation(Long conversationId, Long userId, Boolean isMuted) {
        log.info("设置会话免打扰，会话ID：{}，用户ID：{}，状态：{}", conversationId, userId, isMuted);
        
        ChatParticipant participant = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (participant != null) {
            participant.setIsMuted(isMuted ? 1 : 0);
            participant.setUpdatedAt(LocalDateTime.now());
            chatParticipantMapper.update(participant);
        }
    }
    
    /**
     * 添加会话参与者
     */
    private boolean addParticipant(Long conversationId, Long userId, Integer role) {
        ChatParticipant participant = new ChatParticipant();
        participant.setConversationId(conversationId);
        participant.setUserId(userId);
        participant.setRole(role);
        participant.setIsMuted(0);
        participant.setIsTop(0);
        participant.setJoinTime(LocalDateTime.now());
        participant.setStatus(1);
        participant.setCreatedAt(LocalDateTime.now());
        participant.setUpdatedAt(LocalDateTime.now());
        
        // 检查是否已存在参与者
        ChatParticipant existing = chatParticipantMapper.selectByConversationAndUser(conversationId, userId);
        if (existing != null) {
            // 如果已存在但已退出，则更新状态
            if (existing.getStatus() == 0) {
                existing.setStatus(1);
                existing.setRole(role);
                existing.setJoinTime(LocalDateTime.now());
                existing.setUpdatedAt(LocalDateTime.now());
                return chatParticipantMapper.update(existing) > 0;
            }
            return true;
        }
        
        int result = chatParticipantMapper.insert(participant);
        return result > 0;
    }
}